package com.kk.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author kl
 * @version 1.0
 * @description: TODO
 * @date 2025/10/14 下午4:15
 */
@Component
public class RedisUtils {

    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private RedisUtils(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    // ============================ Key 操作 ============================

    /**
     * 判断 key 是否存在
     */
    public boolean hasKey(String key) {
        return Boolean.TRUE.equals(redisTemplate.hasKey(key));
    }

    /**
     * 删除 key
     */
    public void delete(String key) {
        redisTemplate.delete(key);
    }

    /**
     * 批量删除 key
     */
    public void delete(Collection<String> keys) {
        redisTemplate.delete(keys);
    }

    /**
     * 设置 key 的过期时间（秒）
     */
    public boolean expire(String key, long timeout, TimeUnit unit) {
        return Boolean.TRUE.equals(redisTemplate.expire(key, timeout, unit));
    }

    /**
     * 获取 key 的剩余过期时间（秒）
     */
    public Long getExpire(String key, TimeUnit unit) {
        return redisTemplate.getExpire(key, unit);
    }

    // ============================ Value 操作（String）============================

    /**
     * 普通缓存放入
     */
    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 普通缓存放入并设置时间
     */
    public void set(String key, Object value, long timeout, TimeUnit unit) {
        redisTemplate.opsForValue().set(key, value, timeout, unit);
    }

    /**
     * 获取缓存
     */
    @SuppressWarnings("unchecked")
    public <T> T get(String key) {
        return (T) redisTemplate.opsForValue().get(key);
    }

    /**
     * 递增
     */
    public long increment(String key, long delta) {
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 递减
     */
    public long decrement(String key, long delta) {
        return redisTemplate.opsForValue().decrement(key, delta);
    }

    // ============================ Hash 操作 ============================

    /**
     * HashSet
     */
    public void hSet(String key, String item, Object value) {
        redisTemplate.opsForHash().put(key, item, value);
    }

    /**
     * HashSet 并设置过期时间
     */
    public void hSet(String key, String item, Object value, long timeout, TimeUnit unit) {
        redisTemplate.opsForHash().put(key, item, value);
        expire(key, timeout, unit);
    }

    /**
     * 获取 hash 中的值
     */
    @SuppressWarnings("unchecked")
    public <T> T hGet(String key, String item) {
        return (T) redisTemplate.opsForHash().get(key, item);
    }

    /**
     * 获取 hash 中的所有键值对
     */
    @SuppressWarnings("unchecked")
    public <K, V> Map<K, V> hGetAll(String key) {
        return (Map<K, V>) redisTemplate.opsForHash().entries(key);
    }

    /**
     * 删除 hash 中的一个或多个字段
     */
    public void hDelete(String key, Object... items) {
        redisTemplate.opsForHash().delete(key, items);
    }

    // ============================ Set 操作 ============================

    /**
     * 向 Set 中添加元素
     */
    public void sAdd(String key, Object... values) {
        redisTemplate.opsForSet().add(key, values);
    }

    /**
     * 获取 Set 中的所有元素
     */
    @SuppressWarnings("unchecked")
    public <T> Set<T> sGet(String key) {
        return (Set<T>) redisTemplate.opsForSet().members(key);
    }

    /**
     * 判断 Set 中是否包含某个元素
     */
    public boolean sIsMember(String key, Object value) {
        return Boolean.TRUE.equals(redisTemplate.opsForSet().isMember(key, value));
    }

    // ============================ List 操作 ============================

    /**
     * 向 List 尾部添加元素
     */
    public void lPush(String key, Object value) {
        redisTemplate.opsForList().rightPush(key, value);
    }

    /**
     * 向 List 头部添加元素
     */
    public void lPushLeft(String key, Object value) {
        redisTemplate.opsForList().leftPush(key, value);
    }

    /**
     * 获取 List 指定范围的元素
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> lRange(String key, long start, long end) {
        return (List<T>) redisTemplate.opsForList().range(key, start, end);
    }

    /**
     * 获取 List 长度
     */
    public long lSize(String key) {
        return redisTemplate.opsForList().size(key);
    }

    // ============================ 其他 ============================

    /**
     * 获取 Redis 中所有 key（谨慎使用，仅限测试环境）
     */
    public Set<String> keys(String pattern) {
        return redisTemplate.keys(pattern);
    }
}
